<?php

/**
 * @author [TinyBear]
 * @copyright 2011
 * @action 授权核心类
 */

class TOAuth {

	protected $_sConsumerKey;
	protected $_sConsumerSecret;
	protected $_sToken;
	protected $_sTokenSecret;


	function __construct($sConsumerKey, $sConsumerSecret) {
		$this->_sConsumerKey = $sConsumerKey;
		$this->_sConsumerSecret = $sConsumerSecret;
	}

	function setToken($sToken, $sTokenSecret) {
		$this->_sToken = $sToken;
		$this->_sTokenSecret = $sTokenSecret;
	}


	function getBaseParam() {

		$aReturn = array(
			"oauth_consumer_key" => $this->_sConsumerKey,
			"oauth_nonce" => md5(microtime()),
			"oauth_signature_method" => "HMAC-SHA1",
			"oauth_timestamp" => time(),
			"oauth_version" => "1.0",
		);

		if ($this->_sToken) {
			$aReturn["oauth_token"] = $this->_sToken;
		}
		return $aReturn;
	}

	function send($aParam, $sURL, $sMethod = "GET") {

		if(($sMethod == "POST")&&(isset($aParam['pic']))) {
			
			$file_pic =  $aParam['pic'];
			unset($aParam['pic']); 
        }

		$aParam += $this->getBaseParam();

		$aBaseString = array(
			$sMethod,
			$sURL,
			$this->buildQuery($aParam),
		);

		$sBaseString = implode("&", OAuthUtil::urlencode($aBaseString));
		
		if($this->_sTokenSecret) {
			$sSecret = $this->_sConsumerSecret."&";
			$sSecret .= $this->_sTokenSecret;
		} else {
			$sSecret = $this->_sConsumerSecret."&";
		}		

		$sSignature = hash_hmac('sha1', $sBaseString, $sSecret, true);

		$aParam["oauth_signature"] = base64_encode($sSignature);
			
		if($file_pic) {
			
			$fileX = array("pic" =>$file_pic,);
			$aParam += $fileX;
			
			$boundary = uniqid('------------------');
			$MPboundary = '--'.$boundary;
			$endMPboundary = $MPboundary. '--';
			$multipartbody = '';

			foreach ($aParam as $parameter => $value) { 
					
				if( in_array($parameter,array("pic","image")) )
				{
					$content = $value;
					$filename = 'pic.jpg';
					$mime ='image/jpeg'; 
			
					$multipartbody .= $MPboundary . "\r\n";
					$multipartbody .= 'Content-Disposition: form-data; name="' . $parameter . '"; filename="' . $filename . '"'. "\r\n";
					$multipartbody .= 'Content-Type: '. $mime . "\r\n\r\n";
					$multipartbody .= $content. "\r\n";
				}
				else
				{
					$multipartbody .= $MPboundary . "\r\n";
					$multipartbody .= 'content-disposition: form-data; name="'.$parameter."\"\r\n\r\n";
					$multipartbody .= $value."\r\n";
					
				}    
			} 
				
				$multipartbody .=  $endMPboundary."\r\n";
		}

		$sParam = $this->buildQuery($aParam);
		
		$hCURL = curl_init();

		curl_setopt_array($hCURL, array(
			CURLOPT_HEADER => TRUE,
			CURLOPT_RETURNTRANSFER => TRUE,
		));


		if ($sMethod == "POST") {
			curl_setopt($hCURL, CURLOPT_POST, TRUE);
			
			if($file_pic) {
				$sParam = $multipartbody;
				//echo $multipartbody; //打印图片数据
				$header_array=array(); 
				$header_array = array("Content-Type: multipart/form-data; boundary=" . $boundary , "Expect: ");

			}

			curl_setopt($hCURL, CURLOPT_POSTFIELDS, $sParam);
		}

		
		curl_setopt($hCURL, CURLOPT_HTTPHEADER, $header_array); 
		curl_setopt($hCURL, CURLINFO_HEADER_OUT, TRUE);
		curl_setopt($hCURL, CURLOPT_URL,
		$sURL.($sMethod == "GET" ? "?".$sParam : ""));
		curl_setopt($hCURL, CURLOPT_SSL_VERIFYPEER, false); 
		curl_setopt($hCURL, CURLOPT_SSL_VERIFYHOST, false);

		$sReturn = curl_exec($hCURL);
		$aInfo = curl_getinfo($hCURL);
		//print_r($aInfo);echo "<br>";
		$sReturn = str_replace(array("\r\n", "\r"), "\n", $sReturn);
		list($sReturnHeader, $sReturn) = explode("\n\n", $sReturn, 2);

		return $sReturn;
	}


	function buildQuery($aParam) {

		$aKey = OAuthUtil::urlencode(array_keys($aParam));
		$aValue = OAuthUtil::urlencode(array_values($aParam));
		
		$aParam = array_combine($aKey, $aValue);

		ksort($aParam, SORT_STRING);

		$aPair = array();
		foreach ($aParam as $sKey => $mValue) {
			if (is_array($mValue)) {
				natsort($mValue);
				foreach ($mValue as $sValue) {
					$aPair[] = $sKey.'='.$sValue;
				}
			} else {
				$aPair[] = $sKey.'='.$mValue;
			}
		}
		//print_r($aPair);echo "<br>";
		return implode('&', $aPair);
	}
	
}

class OAuthUtil {

	/**
	 * URL-encode according to RFC 3986
	 * 
	 * @param array|string $input
	 * @return string
	 */
	public static function urlencode($input) {
		if (is_array($input)) {
			return array_map(array('OAuthUtil', 'urlencode'), $input);
		} else if (is_scalar($input)) {
			return str_replace(array('+', '%7E'), array(' ', '~'), rawurlencode($input));
		} else {
			return '';
		}
	}
}

?>